﻿#include "./CameraFactory.h"
#include "./CameraHikVision.h"

namespace Qly{

QList<IndustryCameraInfo> Qly::CameraFactory::availableCameras(QSet<CameraType> types)
{
    QList<Qly::IndustryCameraInfo> infos;
    unsigned int nTLayerType = 0;
    if( types.contains(CameraType::HIK_CameraLink) )
    {
        nTLayerType = MV_CAMERALINK_DEVICE;
    }
    if( types.contains(CameraType::HIK_GIGE) )
    {
        nTLayerType |= MV_GIGE_DEVICE;
    }
    if( types.contains(CameraType::HIK_USB) )
    {
        nTLayerType |= MV_USB_DEVICE;
    }
    return findCameras(nTLayerType);
}

QList<IndustryCameraInfo> Qly::CameraFactory::availableCameras(CameraType type)
{
    QList<Qly::IndustryCameraInfo> infos;
    unsigned int nTLayerType;
    switch(type)
    {
    case CameraType::HIK_GIGE:
        nTLayerType = MV_GIGE_DEVICE;
        break;
    case CameraType::HIK_USB:
        nTLayerType = MV_USB_DEVICE;
        break;
    case CameraType::HIK_CameraLink:
        nTLayerType = MV_CAMERALINK_DEVICE;
        break;
    default:
        return infos;
        break;
    }

    return findCameras(nTLayerType);
}

QList<IndustryCameraInfo> CameraFactory::availableCameras()
{
    unsigned int nTLayerType = MV_GIGE_DEVICE | MV_USB_DEVICE;
    return findCameras(nTLayerType);
}



IndustryCamera *CameraFactory::findCameraByName(QString name, QObject *parent)
{
    Qly::CameraHikVision * camera = new Qly::CameraHikVision(parent);
    if(!camera->openCameraByID(name))
    {
        delete camera;
        camera = nullptr;
        qDebug() << "No HikVision Camera Find";
    }
    return camera;
}



IndustryCamera *CameraFactory::defaultCamera(QObject *parent)
{
    CameraHikVision * camera = new Qly::CameraHikVision(parent);
    if(!camera->openDefaultCamera())
    {
        delete camera;
        camera = nullptr;
        qDebug() << "No HikVision Camera Find";
    }
    return camera;
}

QString CameraFactory::vendorName()
{
    return QString("Hikrobot");
}

QList<IndustryCameraInfo> CameraFactory::findCameras(unsigned int nTLayerType)
{
    QList<Qly::IndustryCameraInfo> infos;
    MV_CC_DEVICE_INFO_LIST stDevList = {0};
    int nRet = MV_CC_EnumDevices(nTLayerType, &stDevList);
    if (MV_OK != nRet)
    {
        qWarning("error: MV_CC_EnumDevices fail [%x]", nRet);
        return infos;
    }
    if (stDevList.nDeviceNum == 0)
    {
        qWarning("no hikvision camera found!");
        return infos;
    }

    for(unsigned int nDeviceIndex = 0; nDeviceIndex < stDevList.nDeviceNum; nDeviceIndex++)
    {
        MV_CC_DEVICE_INFO stDevInfo = {0};
        memcpy(&stDevInfo, stDevList.pDeviceInfo[nDeviceIndex], sizeof(MV_CC_DEVICE_INFO));
        Qly::IndustryCameraInfo info;
        QString serialNumber;
        switch (stDevInfo.nTLayerType )
        {
        case MV_GIGE_DEVICE:
            info.cameraID = QString::fromLocal8Bit(reinterpret_cast<char *>(stDevInfo.SpecialInfo.stGigEInfo.chSerialNumber));
            info.modelName = QString::fromLocal8Bit(reinterpret_cast<char *>(stDevInfo.SpecialInfo.stGigEInfo.chModelName));
            info.vendorName = QString::fromLocal8Bit(reinterpret_cast<char *>(stDevInfo.SpecialInfo.stGigEInfo.chManufacturerName));
            info.type = Qly::HIK_GIGE;
            infos << info;
            break;
        case MV_USB_DEVICE:
            info.cameraID = QString::fromLocal8Bit(reinterpret_cast<char *>(stDevInfo.SpecialInfo.stUsb3VInfo.chSerialNumber));
            info.modelName = QString::fromLocal8Bit(reinterpret_cast<char *>(stDevInfo.SpecialInfo.stUsb3VInfo.chModelName));
            info.vendorName = QString::fromLocal8Bit(reinterpret_cast<char *>(stDevInfo.SpecialInfo.stUsb3VInfo.chManufacturerName));
            info.type = Qly::HIK_USB;
            infos << info;
            break;
        case MV_CAMERALINK_DEVICE:
            info.cameraID = QString::fromLocal8Bit(reinterpret_cast<char *>(stDevInfo.SpecialInfo.stCamLInfo.chSerialNumber));
            info.modelName = QString::fromLocal8Bit(reinterpret_cast<char *>(stDevInfo.SpecialInfo.stCamLInfo.chModelName));
            info.vendorName = QString::fromLocal8Bit(reinterpret_cast<char *>(stDevInfo.SpecialInfo.stCamLInfo.chManufacturerName));
            info.type = Qly::HIK_CameraLink;
            infos << info;
            break;
        }
    }
    return infos;
}

} //namespace Qly

Qly::CameraFactoryInterface *CreateInstance()
{
    Qly::CameraFactory * cameraFactory = new Qly::CameraFactory();
    return cameraFactory;
}

void Release(Qly::CameraFactoryInterface *p)
{
    delete p;
}


bool Qly::CameraFactory::release(IndustryCamera *camera)
{
    Qly::CameraHikVision * pCamera = dynamic_cast<Qly::CameraHikVision *> (camera); // 能够转换成功说明是这个dll new出来的对象。可以删除。
    if(pCamera)
    {
        delete pCamera;
        return true;
    }
    return false; //说明不能删除这个对象
}

